--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Commit b0d47b9ece2aac27f9b52d71eead961754287bf5
Parents : 23a5d03
Author : Ivan <e46112d44649266d71fe2193e00a4710>
Signature : T66BB85Valid, signed by author
Date : 2026-07-25T15:51:04-05:00
chore: release version 4.8.1 with bug fixes and improvements for Windows desktop and packaging
Changes
34 files changed, 259 insertions(+), 33 deletions(-)
Diff
diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml
index 71aa2cc3..ef162a21 100644
--- a/.github/ISSUE_TEMPLATE/bug_report.yml
+++ b/.github/ISSUE_TEMPLATE/bug_report.yml
@@ -13,8 +13,8 @@ body:
id: version
attributes:
label: MeshChatX version
- description: The version shown in Settings or the release you installed (for example 4.8.0).
- placeholder: "4.8.0"
+ description: The version shown in Settings or the release you installed (for example 4.8.1).
+ placeholder: "4.8.1"
validations:
required: true
diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml
index d3c2b7db..13e26d29 100644
--- a/.github/ISSUE_TEMPLATE/feature_request.yml
+++ b/.github/ISSUE_TEMPLATE/feature_request.yml
@@ -14,7 +14,7 @@ body:
attributes:
label: MeshChatX version
description: The version you are using today, if relevant.
- placeholder: "4.8.0"
+ placeholder: "4.8.1"
- type: dropdown
id: os
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 6652be16..fb4a9c2e 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -215,6 +215,9 @@ jobs:
- name: Verify FS sandbox modules bundled in frozen backend
run: bash scripts/ci/github-verify-frozen-sandbox.sh build/exe
+ - name: Verify frozen backend import runtime
+ run: bash scripts/ci/github-verify-frozen-runtime.sh build/exe
+
- name: Verify frozen backend has no package bloat
run: bash scripts/ci/verify-package-contents.sh frozen build/exe
@@ -259,6 +262,8 @@ jobs:
.artifacts/linux-build-check/build/exe
bash scripts/ci/github-verify-frozen-sandbox.sh \
.artifacts/linux-build-check/build/exe
+ bash scripts/ci/github-verify-frozen-runtime.sh \
+ .artifacts/linux-build-check/build/exe
bash scripts/ci/verify-package-contents.sh frozen \
.artifacts/linux-build-check/build/exe
echo "Linux build artifact download + content validation passed."
diff --git a/CHANGELOG.md b/CHANGELOG.md
index c3ed9c6e..1820bf25 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,13 @@
All notable changes to this project will be documented in this file.
+## [4.8.1] - 2026-07-25
+
+### Fixed
+
+- **Windows desktop**: Frozen backends start again instead of failing when aiohttp imports the standard library email package.
+- **Desktop packaging**: Only the correct LXST filterlib binary ships per platform so integrity checks match the installer. CI runs a frozen import smoke test before release.
+
## [4.8.0] - 2026-07-25
### Added
diff --git a/README.md b/README.md
index 8524a404..5565e325 100644
--- a/README.md
+++ b/README.md
@@ -441,7 +441,7 @@ task build
## Versioning
-Current version in this repo is `4.8.0`.
+Current version in this repo is `4.8.1`.
- **`package.json`** `version` is the only value you edit for a release bump.
- Run **`pnpm run version:sync`** (also run at the start of **`pnpm run build`**) to propagate that version into **`pyproject.toml`**, **`meshchatx/src/version.py`**, **`THIRD_PARTY_NOTICES.txt`** (product line), **README** / **lang/README.\*** “current version” lines, **`docs/meshchatx_on_raspberry_pi.md`** pipx example, and **`packaging/arch/PKGBUILD`** helpers.
diff --git a/android/app/build.gradle b/android/app/build.gradle
index 47737289..d8a6f180 100644
--- a/android/app/build.gradle
+++ b/android/app/build.gradle
@@ -50,8 +50,8 @@ android {
applicationId "com.meshchatx"
minSdk 24
targetSdk 35
- versionCode 48000
- versionName "4.8.0"
+ versionCode 48001
+ versionName "4.8.1"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
ndk {
diff --git a/cx_setup.py b/cx_setup.py
index 4d597475..05a0a035 100644
--- a/cx_setup.py
+++ b/cx_setup.py
@@ -68,6 +68,9 @@ packages = [
"cffi",
"ply",
"bleak",
+ # aiohttp pulls stdlib email at runtime. Keep the full tree out of library.zip
+ # so relative imports like email._policybase -> email.header work on Windows.
+ "email",
]
# Keep FS sandbox helpers even when import tracing is incomplete (Windows
@@ -77,6 +80,7 @@ includes = [
"meshchatx.src.backend.appcontainer_sandbox",
"meshchatx.src.backend.appcontainer_launcher",
"meshchatx.src.backend.seccomp_sandbox",
+ "meshchatx.src.backend.frozen_freeze_probe",
]
if sys.version_info >= (3, 13):
@@ -110,6 +114,7 @@ setup(
"distutils",
"pkg_resources",
],
+ "zip_exclude_packages": ["email"],
"optimize": 2,
"build_exe": build_exe_dir,
"replace_paths": [
diff --git a/docs/en/platform-guides/raspberry-pi.md b/docs/en/platform-guides/raspberry-pi.md
index 9e200a19..4c047942 100644
--- a/docs/en/platform-guides/raspberry-pi.md
+++ b/docs/en/platform-guides/raspberry-pi.md
@@ -61,17 +61,17 @@ source ~/.profile
## 3) Install MeshChatX with pipx (recommended)
-Preferred option (recommended): install from a release wheel (4.8.0 or newer),
+Preferred option (recommended): install from a release wheel (4.8.1 or newer),
because the wheel bundles frontend assets.
```bash
pipx install /path/to/reticulum_meshchatx-<version>-py3-none-any.whl
```
-Direct example (v4.8.0):
+Direct example (v4.8.1):
```bash
-pipx install "https://github.com/Quad4-Software/MeshChatX/releases/download/v4.8.0/reticulum_meshchatx-4.8.0-py3-none-any.whl"
+pipx install "https://github.com/Quad4-Software/MeshChatX/releases/download/v4.8.1/reticulum_meshchatx-4.8.1-py3-none-any.whl"
```
`py3-none-any` wheels are architecture-independent, so the same wheel artifact
@@ -93,7 +93,7 @@ cd ~/meshchatx
python3 -m venv .venv
source .venv/bin/activate
python -m pip install --upgrade pip
-python -m pip install "https://github.com/Quad4-Software/MeshChatX/releases/download/v4.8.0/reticulum_meshchatx-4.8.0-py3-none-any.whl"
+python -m pip install "https://github.com/Quad4-Software/MeshChatX/releases/download/v4.8.1/reticulum_meshchatx-4.8.1-py3-none-any.whl"
```
Run command in venv mode:
diff --git a/lang/README.de.md b/lang/README.de.md
index 869a892d..26f3afb4 100644
--- a/lang/README.de.md
+++ b/lang/README.de.md
@@ -352,7 +352,7 @@ task build
## Versionierung
-Aktuelle Version in diesem Repository: `4.8.0`.
+Aktuelle Version in diesem Repository: `4.8.1`.
- Fuer Release-Bumps bearbeiten Sie **nur** `version` in **`package.json`**.
- **`pnpm run version:sync`** (wird auch zu Beginn von **`pnpm run build`** ausgefuehrt) verbreitet diese Version in **`pyproject.toml`**, **`meshchatx/src/version.py`**, **`THIRD_PARTY_NOTICES.txt`** (Produktzeile), **README** / **lang/README.\*** (Zeilen mit aktueller Version), **`docs/meshchatx_on_raspberry_pi.md`** (pipx-Beispiel) und Hilfsfelder in **`packaging/arch/PKGBUILD`**.
diff --git a/lang/README.it.md b/lang/README.it.md
index 9c373d2f..265ef69d 100644
--- a/lang/README.it.md
+++ b/lang/README.it.md
@@ -352,7 +352,7 @@ I target `Makefile` sono wrapper sottili che delegano a `task` (stessi comandi d
## Versionamento
-Versione attuale nel repository: `4.8.0`.
+Versione attuale nel repository: `4.8.1`.
- L'unico valore che modifichi per un bump di release e **`version` in `package.json`**.
- Esegui **`pnpm run version:sync`** (all'inizio anche di **`pnpm run build`**) per propagare in **`pyproject.toml`**, **`meshchatx/src/version.py`**, **`THIRD_PARTY_NOTICES.txt`** (riga prodotto), **README** / **lang/README.\*** (righe "versione attuale"), **esempio pipx in `docs/meshchatx_on_raspberry_pi.md`**, e aiuti in **`packaging/arch/PKGBUILD`**.
diff --git a/lang/README.ja.md b/lang/README.ja.md
index 38a4a6dc..5fc4a7fb 100644
--- a/lang/README.ja.md
+++ b/lang/README.ja.md
@@ -352,7 +352,7 @@ task build
## バージョン管理
-このリポジトリの現在のバージョンは `4.8.0` です。
+このリポジトリの現在のバージョンは `4.8.1` です。
- リリースのバージョン上げは **`package.json` の `version` のみ**編集します。
- **`pnpm run version:sync`**(**`pnpm run build`** 開始時にも実行)で、**`pyproject.toml`**、**`meshchatx/src/version.py`**、**`THIRD_PARTY_NOTICES.txt`**(製品行)、**README** / **lang/README.\***(現在のバージョン行)、**`docs/meshchatx_on_raspberry_pi.md`** の pipx 例、**`packaging/arch/PKGBUILD`** の補助フィールドに反映します。
diff --git a/lang/README.ru.md b/lang/README.ru.md
index efe870b2..e4924b04 100644
--- a/lang/README.ru.md
+++ b/lang/README.ru.md
@@ -352,7 +352,7 @@ task build
## Версионирование
-Текущая версия в репозитории: `4.8.0`.
+Текущая версия в репозитории: `4.8.1`.
- Редактируйте для релизного бампа **только** поле `version` в **`package.json`**.
- Команда **`pnpm run version:sync`** (также в начале **`pnpm run build`**) распространяет эту версию в **`pyproject.toml`**, **`meshchatx/src/version.py`**, **`THIRD_PARTY_NOTICES.txt`** (строка продукта), **README** / **lang/README.\*** (строки «текущая версия»), **`docs/meshchatx_on_raspberry_pi.md`** (пример pipx) и вспомогательные поля **`packaging/arch/PKGBUILD`**.
diff --git a/lang/README.zh.md b/lang/README.zh.md
index 33ad0022..a3b2a40e 100644
--- a/lang/README.zh.md
+++ b/lang/README.zh.md
@@ -352,7 +352,7 @@ task build
## 版本管理
-本仓库当前版本: `4.8.0`。
+本仓库当前版本: `4.8.1`。
- 发布版本号**只**改 **`package.json` 的 `version`**。
- 运行 **`pnpm run version:sync`**(在 **`pnpm run build`** 开头也会执行)可将该版本同步到 **`pyproject.toml`**、**`meshchatx/src/version.py`**、**`THIRD_PARTY_NOTICES.txt`**(产品行)、**README** / **lang/README.\*** 中的“当前版本”行、**`docs/meshchatx_on_raspberry_pi.md`** 的 pipx 示例,以及 **`packaging/arch/PKGBUILD`** 的辅助字段。
diff --git a/meshchatx.rsm b/meshchatx.rsm
index aa8d83ea..79fd0a57 100644
Binary files a/meshchatx.rsm and b/meshchatx.rsm differ
diff --git a/meshchatx/__init__.py b/meshchatx/__init__.py
index c28f1b82..3abc356e 100644
--- a/meshchatx/__init__.py
+++ b/meshchatx/__init__.py
@@ -3,8 +3,7 @@
"""Reticulum MeshChatX - A mesh network communications app."""
# Synced from package.json via scripts/sync_version.js (also writes meshchatx/src/version.py).
-__version__ = "4.8.0"
-
+__version__ = "4.8.1"
# LXST vendored pyogg can NameError on import when libopus is present but
# libogg is not. Apply before any meshchatx module imports LXST.
try:
diff --git a/meshchatx/src/backend/bake_frozen_lxst_native.py b/meshchatx/src/backend/bake_frozen_lxst_native.py
new file mode 100644
index 00000000..6f9a68ed
--- /dev/null
+++ b/meshchatx/src/backend/bake_frozen_lxst_native.py
@@ -0,0 +1,57 @@
+# SPDX-License-Identifier: 0BSD
+
+"""Prune alien LXST filterlib blobs after cx_Freeze."""
+
+from __future__ import annotations
+
+import sys
+import sysconfig
+from pathlib import Path
+
+
+def _should_keep_filterlib(name: str, ext_suffix: str) -> bool:
+ if sys.platform == "win32" and name == "filterlib.dll":
+ return True
+ if ext_suffix and name == f"filterlib{ext_suffix}":
+ return True
+ return False
+
+
+def bake_lxst_filterlib(build_dir: Path) -> None:
+ lxst = build_dir / "lib" / "LXST"
+ if not lxst.is_dir():
+ raise SystemExit(f"bake_frozen_lxst_native: missing {lxst}")
+
+ ext_suffix = sysconfig.get_config_var("EXT_SUFFIX") or ""
+ removed = 0
+ kept: list[str] = []
+ for path in sorted(lxst.glob("filterlib*")):
+ if not path.is_file():
+ continue
+ if _should_keep_filterlib(path.name, ext_suffix):
+ kept.append(path.name)
+ continue
+ path.unlink()
+ removed += 1
+
+ if not kept:
+ raise SystemExit(
+ "bake_frozen_lxst_native: no filterlib native artifact for this platform "
+ f"({sys.platform}, EXT_SUFFIX={ext_suffix!r})"
+ )
+
+ print(
+ f"bake_frozen_lxst_native: OK kept {kept!r} (removed {removed} alien blob(s))"
+ )
+
+
+def main() -> None:
+ if len(sys.argv) != 2:
+ raise SystemExit(
+ "usage: python -m meshchatx.src.backend.bake_frozen_lxst_native <build dir>"
+ )
+ bake_lxst_filterlib(Path(sys.argv[1]).resolve())
+
+
+if __name__ == "__main__":
+ main()
diff --git a/meshchatx/src/backend/data/THIRD_PARTY_NOTICES.txt b/meshchatx/src/backend/data/THIRD_PARTY_NOTICES.txt
index c91070df..e4e85765 100644
--- a/meshchatx/src/backend/data/THIRD_PARTY_NOTICES.txt
+++ b/meshchatx/src/backend/data/THIRD_PARTY_NOTICES.txt
@@ -86,7 +86,7 @@ pycparser 3.0
pyserial 3.5
License: BSD
Author: Chris Liechti
-reticulum-meshchatx 4.8.0
+reticulum-meshchatx 4.8.1
License: 0BSD AND MIT
Author: Quad4
rns 1.4.1
diff --git a/meshchatx/src/backend/data/licenses_backend.json b/meshchatx/src/backend/data/licenses_backend.json
index cd67a215..ebb12da2 100644
--- a/meshchatx/src/backend/data/licenses_backend.json
+++ b/meshchatx/src/backend/data/licenses_backend.json
@@ -50,7 +50,7 @@
{
"name": "cbor2",
"version": "6.1.1",
- "author": "Alex Gr\u00f6nholm <alex.gronholm@nextday.fi>",
+ "author": "Alex Grönholm <alex.gronholm@nextday.fi>",
"license": "MIT"
},
{
@@ -157,7 +157,7 @@
},
{
"name": "reticulum-meshchatx",
- "version": "4.8.0",
+ "version": "4.8.1",
"author": "Quad4",
"license": "0BSD AND MIT"
},
diff --git a/meshchatx/src/backend/frozen_freeze_probe.py b/meshchatx/src/backend/frozen_freeze_probe.py
new file mode 100644
index 00000000..b3ccc821
--- /dev/null
+++ b/meshchatx/src/backend/frozen_freeze_probe.py
@@ -0,0 +1,52 @@
+# SPDX-License-Identifier: 0BSD
+
+"""Import probes for cx_Freeze desktop builds.
+
+Invoked from CI and build-backend via:
+
+ ReticulumMeshChatX --meshchatx-run-module meshchatx.src.backend.frozen_freeze_probe
+"""
+
+from __future__ import annotations
+
+import importlib.util
+import sys
+import sysconfig
+from pathlib import Path
+
+
+def _lxst_filterlib_path() -> Path | None:
+ spec = importlib.util.find_spec("LXST")
+ if spec is None or not spec.submodule_search_locations:
+ return None
+ root = Path(next(iter(spec.submodule_search_locations)))
+ if not root.is_dir():
+ return None
+ ext = sysconfig.get_config_var("EXT_SUFFIX") or ""
+ candidates: list[Path] = []
+ if sys.platform == "win32":
+ candidates.append(root / "filterlib.dll")
+ if ext:
+ candidates.append(root / f"filterlib{ext}")
+ for path in candidates:
+ if path.is_file():
+ return path
+ return None
+
+
+def main() -> None:
+ import email.header # noqa: F401
+ import email.message # noqa: F401
+ import email.policy # noqa: F401
+
+ import aiohttp # noqa: F401
+
+ native = _lxst_filterlib_path()
+ if native is None:
+ raise SystemExit("frozen-freeze-probe: LXST filterlib native artifact missing")
+
+ print("frozen-freeze-probe ok", flush=True)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/meshchatx/src/backend/self_check.py b/meshchatx/src/backend/self_check.py
index 84722b7a..d1099443 100644
--- a/meshchatx/src/backend/self_check.py
+++ b/meshchatx/src/backend/self_check.py
@@ -17,6 +17,7 @@ from typing import Any
from meshchatx.src.backend import self_check_probe as _self_check_probe # noqa: F401
_CRITICAL_IMPORTS = (
+ "email.header",
"RNS",
"LXMF",
"lxmfy",
diff --git a/meshchatx/src/frontend/public/meshchatx-docs/en/platform-guides/raspberry-pi.md b/meshchatx/src/frontend/public/meshchatx-docs/en/platform-guides/raspberry-pi.md
index 9e200a19..4c047942 100644
--- a/meshchatx/src/frontend/public/meshchatx-docs/en/platform-guides/raspberry-pi.md
+++ b/meshchatx/src/frontend/public/meshchatx-docs/en/platform-guides/raspberry-pi.md
@@ -61,17 +61,17 @@ source ~/.profile
## 3) Install MeshChatX with pipx (recommended)
-Preferred option (recommended): install from a release wheel (4.8.0 or newer),
+Preferred option (recommended): install from a release wheel (4.8.1 or newer),
because the wheel bundles frontend assets.
```bash
pipx install /path/to/reticulum_meshchatx-<version>-py3-none-any.whl
```
-Direct example (v4.8.0):
+Direct example (v4.8.1):
```bash
-pipx install "https://github.com/Quad4-Software/MeshChatX/releases/download/v4.8.0/reticulum_meshchatx-4.8.0-py3-none-any.whl"
+pipx install "https://github.com/Quad4-Software/MeshChatX/releases/download/v4.8.1/reticulum_meshchatx-4.8.1-py3-none-any.whl"
```
`py3-none-any` wheels are architecture-independent, so the same wheel artifact
@@ -93,7 +93,7 @@ cd ~/meshchatx
python3 -m venv .venv
source .venv/bin/activate
python -m pip install --upgrade pip
-python -m pip install "https://github.com/Quad4-Software/MeshChatX/releases/download/v4.8.0/reticulum_meshchatx-4.8.0-py3-none-any.whl"
+python -m pip install "https://github.com/Quad4-Software/MeshChatX/releases/download/v4.8.1/reticulum_meshchatx-4.8.1-py3-none-any.whl"
```
Run command in venv mode:
diff --git a/meshchatx/src/frontend/public/service-worker.js b/meshchatx/src/frontend/public/service-worker.js
index 5c848422..3dadc72e 100644
--- a/meshchatx/src/frontend/public/service-worker.js
+++ b/meshchatx/src/frontend/public/service-worker.js
@@ -371,6 +371,7 @@ function createShellRuntime(options) {
}
// SPDX-License-Identifier: 0BSD
+/* global ["/","/boot-theme.js","/manifest.json","/favicons/favicon-512x512.png"], cacheNameForBuild, createShellRuntime, SHELL_FALLBACK_URL, NAV_NETWORK_TIMEOUT_MS, UPDATE_MESSAGE_TYPE */
/**
* MeshChatX app-shell service worker bootstrap.
* Preceded at build time by inlined swCachePolicy.js + swShellRuntime.js.
diff --git a/meshchatx/src/frontend/public/vendor/visualiser-wasm/integrity.json b/meshchatx/src/frontend/public/vendor/visualiser-wasm/integrity.json
index 555a4c91..fa384b50 100644
--- a/meshchatx/src/frontend/public/vendor/visualiser-wasm/integrity.json
+++ b/meshchatx/src/frontend/public/vendor/visualiser-wasm/integrity.json
@@ -1,6 +1,6 @@
{
"version": "1.2.0",
- "wasm": "sha384-u89AYwtv9w30MHieh7YmTmorpfsR5A8bh+9wRJR1rgvqaRc2xjgxEiM5mvJAsA9V",
+ "wasm": "sha384-6bz7NFPqx6GPHO+/fb7VihhQ9OCCl5yucvUB+Z1weaBTIB/Le2ekjfJklRKbi8TD",
"wasmExec": "sha384-PWCs+V4BDf9yY1yjkD/p+9xNEs4iEbuvq+HezAOJiY3XL5GI6VyJXMsvnjiwNbce",
"wasmExecSource": "/usr/lib/go/lib/wasm/wasm_exec.js"
}
diff --git a/meshchatx/src/version.py b/meshchatx/src/version.py
index 86c13caa..726eccb0 100644
--- a/meshchatx/src/version.py
+++ b/meshchatx/src/version.py
@@ -3,4 +3,4 @@
Do not edit by hand. Run: pnpm run version:sync
"""
-__version__ = "4.8.0"
+__version__ = "4.8.1"
diff --git a/package.json b/package.json
index 25704bcd..b89a5755 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "reticulum-meshchatx",
- "version": "4.8.0",
+ "version": "4.8.1",
"description": "A simple mesh network communications app powered by the Reticulum Network Stack",
"homepage": "https://github.com/Quad4-Software/MeshChatX",
"desktopName": "reticulum-meshchatx.desktop",
diff --git a/packaging/arch/.SRCINFO b/packaging/arch/.SRCINFO
index 9fbfe679..5bb2c0a4 100644
--- a/packaging/arch/.SRCINFO
+++ b/packaging/arch/.SRCINFO
@@ -1,6 +1,6 @@
pkgbase = reticulum-meshchatx-git
pkgdesc = A simple mesh network communications app powered by the Reticulum Network Stack
- pkgver = 4.8.0.r0.gebacc00
+ pkgver = 4.8.1.r0.gebacc00
pkgrel = 1
url = https://github.com/Quad4-Software/MeshChatX
arch = x86_64
diff --git a/packaging/arch/PKGBUILD b/packaging/arch/PKGBUILD
index 516d14ea..a7150bcb 100644
--- a/packaging/arch/PKGBUILD
+++ b/packaging/arch/PKGBUILD
@@ -1,7 +1,7 @@
# Maintainer: Ivan <ivan@quad4.io>
pkgname=reticulum-meshchatx-git
_pkgname=reticulum-meshchatx
-pkgver=4.8.0.r0.gebacc00
+pkgver=4.8.1.r0.gebacc00
pkgrel=1
pkgdesc="A simple mesh network communications app powered by the Reticulum Network Stack"
arch=('x86_64' 'aarch64')
@@ -19,7 +19,7 @@ sha256sums=('SKIP'
pkgver() {
cd "$_pkgname"
git describe --long --tags 2>/dev/null | sed 's/^v//;s/\([^-]*-g\)/r\1/;s/-/./g' || \
- printf "4.8.0.r%s.%s" "$(git rev-list --count HEAD)" "$(git rev-parse --short HEAD)"
+ printf "4.8.1.r%s.%s" "$(git rev-list --count HEAD)" "$(git rev-parse --short HEAD)"
}
prepare() {
diff --git a/pyproject.toml b/pyproject.toml
index 7e001e79..eaf9ab2a 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -1,6 +1,6 @@
[project]
name = "reticulum-meshchatx"
-version = "4.8.0"
+version = "4.8.1"
description = "A simple mesh network communications app powered by the Reticulum Network Stack"
authors = [
{name = "Quad4"}
diff --git a/scripts/build-backend.js b/scripts/build-backend.js
index 0df1611a..e4a5f589 100755
--- a/scripts/build-backend.js
+++ b/scripts/build-backend.js
@@ -328,6 +328,25 @@ try {
if (isDarwin) {
stripPythonBytecodeArtifacts(buildDir);
}
+ const bakeCmdParts = pythonCmd.trim().split(/\s+/).filter(Boolean);
+ const bakeCmd = bakeCmdParts[0];
+ let bakeArgs = [
+ ...bakeCmdParts.slice(1),
+ "-m",
+ "meshchatx.src.backend.bake_frozen_lxst_native",
+ buildDir,
+ ];
+ let bakeSpawnCmd = bakeCmd;
+ if (rosettaX64) {
+ bakeSpawnCmd = "arch";
+ bakeArgs = ["-x86_64", bakeCmd, ...bakeArgs];
+ }
+ const bakeResult = spawnSync(bakeSpawnCmd, bakeArgs, {
+ stdio: "inherit",
+ shell: false,
+ env: env,
+ });
+ failOnSpawnResult("LXST filterlib prune", bakeResult);
if (!verifyBinaryArchitecture(buildDir, arch, targetName)) {
process.exit(1);
}
diff --git a/scripts/build/reticulum_docs_bundle.json b/scripts/build/reticulum_docs_bundle.json
index f22f0f35..1d73ba37 100644
--- a/scripts/build/reticulum_docs_bundle.json
+++ b/scripts/build/reticulum_docs_bundle.json
@@ -1,6 +1,6 @@
{
"dest": "meshchatx/public/reticulum-docs-bundled/current",
- "fetched_utc": "2026-07-24T10:01:13Z",
+ "fetched_utc": "2026-07-25T20:12:03Z",
"html_files": 206,
"skipped_binary_files": 2,
"source_url": "https://codeload.github.com/markqvist/reticulum_website/zip/refs/heads/master"
diff --git a/scripts/ci/github-build-windows.sh b/scripts/ci/github-build-windows.sh
index 36777f85..5613979f 100755
--- a/scripts/ci/github-build-windows.sh
+++ b/scripts/ci/github-build-windows.sh
@@ -29,6 +29,7 @@ bash scripts/ci/github-verify-electron-dist.sh win
# Ensure AppContainer/Landlock/Seccomp modules shipped in the frozen backend.
if [[ -d build/exe ]]; then
bash scripts/ci/github-verify-frozen-sandbox.sh build/exe
+ bash scripts/ci/github-verify-frozen-runtime.sh build/exe
fi
# Optional packaged smoke (manual / future CI job on a Windows runner):
diff --git a/scripts/ci/github-verify-frozen-runtime.sh b/scripts/ci/github-verify-frozen-runtime.sh
new file mode 100644
index 00000000..9c653d71
--- /dev/null
+++ b/scripts/ci/github-verify-frozen-runtime.sh
@@ -0,0 +1,51 @@
+#!/usr/bin/env bash
+# Run import probes inside the cx_Freeze binary (aiohttp/email/LXST natives).
+set -euo pipefail
+
+ROOT="$(cd "$(dirname "$0")/../.." && pwd)"
+BUILD_EXE="${1:-${ROOT}/build/exe}"
+
+if [[ ! -d "${BUILD_EXE}" ]]; then
+ echo "cx_Freeze output not found at ${BUILD_EXE}" >&2
+ exit 1
+fi
+
+if [[ ! -d "${BUILD_EXE}/lib" ]]; then
+ for sub in "${BUILD_EXE}"/*; do
+ if [[ -d "${sub}/lib" ]]; then
+ BUILD_EXE="${sub}"
+ break
+ fi
+ done
+fi
+
+EXE=""
+for name in ReticulumMeshChatX ReticulumMeshChatX.exe; do
+ if [[ -x "${BUILD_EXE}/${name}" ]] || [[ -f "${BUILD_EXE}/${name}" ]]; then
+ EXE="${BUILD_EXE}/${name}"
+ break
+ fi
+done
+
+if [[ -z "${EXE}" ]]; then
+ echo "frozen runtime verify: backend executable not found under ${BUILD_EXE}" >&2
+ exit 1
+fi
+
+if [[ ! -d "${BUILD_EXE}/lib/email" ]]; then
+ echo "frozen runtime verify: lib/email missing (stdlib email must not live only in library.zip)" >&2
+ exit 1
+fi
+
+if [[ ! -f "${BUILD_EXE}/lib/email/header.py" ]]; then
+ shopt -s nullglob
+ headers=("${BUILD_EXE}/lib/email/header"*.pyc)
+ shopt -u nullglob
+ if [[ ${#headers[@]} -eq 0 ]]; then
+ echo "frozen runtime verify: email.header module missing under lib/email" >&2
+ exit 1
+ fi
+fi
+
+"${EXE}" --meshchatx-run-module meshchatx.src.backend.frozen_freeze_probe
+echo "frozen runtime verify: OK (${EXE})"
diff --git a/tests/backend/test_bake_frozen_lxst_native.py b/tests/backend/test_bake_frozen_lxst_native.py
new file mode 100644
index 00000000..76067f11
--- /dev/null
+++ b/tests/backend/test_bake_frozen_lxst_native.py
@@ -0,0 +1,28 @@
+# SPDX-License-Identifier: 0BSD
+
+from __future__ import annotations
+
+import sys
+from pathlib import Path
+
+import pytest
+
+from meshchatx.src.backend.bake_frozen_lxst_native import bake_lxst_filterlib
+
+
+def test_bake_lxst_filterlib_prunes_alien_blobs(tmp_path: Path, monkeypatch: pytest.MonkeyPatch) -> None:
+ lxst = tmp_path / "lib" / "LXST"
+ lxst.mkdir(parents=True)
+ (lxst / "filterlib.dll").write_bytes(b"win")
+ (lxst / "filterlib.cpython-314-x86_64-linux-gnu.so").write_bytes(b"linux")
+
+ monkeypatch.setattr(sys, "platform", "win32", raising=False)
+ monkeypatch.setattr(
+ "meshchatx.src.backend.bake_frozen_lxst_native.sysconfig.get_config_var",
+ lambda name: ".cp314-win_amd64.pyd" if name == "EXT_SUFFIX" else None,
+ )
+
+ bake_lxst_filterlib(tmp_path)
+
+ assert (lxst / "filterlib.dll").is_file()
+ assert not (lxst / "filterlib.cpython-314-x86_64-linux-gnu.so").exists()
diff --git a/uv.lock b/uv.lock
index 4c4bc705..56ff55a2 100644
--- a/uv.lock
+++ b/uv.lock
@@ -2000,7 +2000,7 @@ wheels = [
[[package]]
name = "reticulum-meshchatx"
-version = "4.8.0"
+version = "4.8.1"
source = { editable = "." }
dependencies = [
{ name = "aiohttp" },
──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────